package uicgas.pump.gui.impl;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import uicgas.globaldevice.CardReader;
import uicgas.pump.PumpStateChangeNotifiable;
import uicgas.pump.device.PhysicalPump.GasolineGrade;
import uicgas.pump.impl.PumpLogicImpl;

public class UserInputSimulator extends JFrame implements
		PumpStateChangeNotifiable
{

	private static final long serialVersionUID = -6433963493925000872L;

	private JPanel contentPane;

	private JButton btnSwipeCard = null;
	private JButton btnBeginPumping = null;
	private JButton btnFinishPumping = null;

	/**
	 * Create the frame.
	 */
	public UserInputSimulator(final PumpLogicImpl pumpLogic,
			final CardReader cardReader)
	{
		pumpLogic.addPumpStateChangeListener(this);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 393, 79);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		gbl_contentPane.rowHeights = new int[] {
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0 };
		gbl_contentPane.columnWeights = new double[] {
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				Double.MIN_VALUE };
		gbl_contentPane.rowWeights = new double[] {
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				0.0,
				Double.MIN_VALUE };
		contentPane.setLayout(gbl_contentPane);

		btnSwipeCard = new JButton("  Swipe Card  ");
		btnSwipeCard.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				cardReader.notifyCardSwipe();

				//				invokeInAnotherThread(new Callback()
				//				{
				//					@Override
				//					public void invoke()
				//					{
				//						new ActivatePump(pumpLogic, pumpLogic
				//								.getCommunication()).executeRemoteCommand();
				//
				//					}
				//
				//					@Override
				//					public boolean needWait()
				//					{
				//						return true;
				//					}
				//				});
			}
		});
		GridBagConstraints gbc_btnSwipeCard = new GridBagConstraints();
		gbc_btnSwipeCard.fill = GridBagConstraints.VERTICAL;
		gbc_btnSwipeCard.gridheight = 4;
		gbc_btnSwipeCard.insets = new Insets(0, 0, 5, 5);
		gbc_btnSwipeCard.gridx = 2;
		gbc_btnSwipeCard.gridy = 3;
		contentPane.add(btnSwipeCard, gbc_btnSwipeCard);

		btnBeginPumping = new JButton("Begin Pumping");
		btnBeginPumping.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				invokeInAnotherThread(new Callback()
				{
					@Override
					public void invoke()
					{
						pumpLogic.beginToPump();
					}

					@Override
					public boolean needWait()
					{
						return false;
					}
				});

			}
		});
		GridBagConstraints gbc_btnBeginPumping = new GridBagConstraints();
		gbc_btnBeginPumping.fill = GridBagConstraints.VERTICAL;
		gbc_btnBeginPumping.gridheight = 4;
		gbc_btnBeginPumping.insets = new Insets(0, 0, 5, 5);
		gbc_btnBeginPumping.gridx = 3;
		gbc_btnBeginPumping.gridy = 3;
		contentPane.add(btnBeginPumping, gbc_btnBeginPumping);

		btnFinishPumping = new JButton("Finish Pumping");
		GridBagConstraints gbc_btnFinishPumping = new GridBagConstraints();
		gbc_btnFinishPumping.fill = GridBagConstraints.VERTICAL;
		gbc_btnFinishPumping.gridheight = 4;
		gbc_btnFinishPumping.insets = new Insets(0, 0, 5, 5);
		gbc_btnFinishPumping.gridx = 4;
		gbc_btnFinishPumping.gridy = 3;
		btnFinishPumping.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				invokeInAnotherThread(new Callback()
				{
					@Override
					public void invoke()
					{
						pumpLogic.finishPumping();
					}

					@Override
					public boolean needWait()
					{
						return false;
					}
				});
			}
		});

		contentPane.add(btnFinishPumping, gbc_btnFinishPumping);

		setButtonsToInitialStates();
	}

	private void setButtonsToInitialStates()
	{
		btnSwipeCard.setEnabled(true);
		btnBeginPumping.setEnabled(false);
		btnFinishPumping.setEnabled(false);
	}

	private void setButtonsToReadyToPumpStates()
	{
		btnSwipeCard.setEnabled(false);
		btnBeginPumping.setEnabled(true);
		btnFinishPumping.setEnabled(false);
	}

	private void setButtonsToReadyToFinishPumpStates()
	{
		btnSwipeCard.setEnabled(false);
		btnBeginPumping.setEnabled(false);
		btnFinishPumping.setEnabled(true);
	}

	private static interface Callback
	{
		void invoke();

		boolean needWait();
	}

	private void invokeInAnotherThread(final Callback callback)
	{
		new Thread()
		{
			public void run()
			{
				if (callback.needWait())
				{
					try
					{
						Thread.sleep(2000);
					}
					catch (InterruptedException e)
					{
					}
				}

				callback.invoke();
			}
		}.start();
	}

	@Override
	public void ammountChanged(GasolineGrade grade, double currentGasAmount,
			double currentMoneyAmount)
	{
		if (!btnBeginPumping.isEnabled())
		{
			return;
		}

		setButtonsToReadyToFinishPumpStates();
	}

	@Override
	public void finishedPumping(GasolineGrade grade, double currentGasAmount,
			double currentMoneyAmount)
	{
		setButtonsToInitialStates();
	}

	@Override
	public void readyForPumping()
	{
		setButtonsToReadyToPumpStates();
	}

}
